﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AutoMapper;
using Confluent.Kafka;

 

using LinqKit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MySql.Data.MySqlClient;
using Consul;
using Cctegaq.Api.Configurations;
using Microsoft.Extensions.Options;

using System.Net.Http;
using RestSharp;
using System.ComponentModel.DataAnnotations;
using Spire.Doc;


using Ccteg.Common;
using CCcteg.Common;
using Ccteg.DB;
using Cari.IBP.Platform.Utility;
using Cari.IBP.Platform.Sidecar;

namespace Cctegaq.Api.Controllers.Api.V1.Rbac
{
    /// <summary>
    /// 我的测试接口
    /// </summary>
    [ApiController]
    [Route("api/v1/rbac/[controller]/[action]")]
    public class TestApiController : IbpControllerBase
    {
        public readonly ConsulServiceSettings _consulOption;
        private readonly MySqlDbContext _dbContext;
        private readonly IMapper _mapper;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly ApplicationData  _ApplicationData;
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="mapper"></param>
        //public TestApiController(MySqlDbContext dbContext, IMapper mapper, ConsulServiceSettings consulOption)
        //{
        //    _dbContext = dbContext;
        //    _mapper = mapper;
        //    _consulOption = consulOption;
        //}
        public TestApiController(MySqlDbContext dbContext, ApplicationData ApplicationData ,IMapper mapper, IOptionsMonitor<ConsulServiceSettings> consulOption, IHttpClientFactory httpClientFactory)
        {
            _dbContext = dbContext;
            _mapper = mapper;
            _httpClientFactory = httpClientFactory;
            _ApplicationData = ApplicationData;
            _consulOption = consulOption.CurrentValue; //IOptions 需要每次重新启动项目加载配置，IOptionsMonitor 每次更改配置都会重新加载，不需要重新启动项目。
        }
        /// <summary>
        /// test test
        /// </summary>
        /// <returns></returns>

        [HttpPost]

        public IActionResult test()
        {

          var cc=  CurrentUser.UserInfo.DisplayName;

            //string parameterNames = "1";
            //int MoneyType = 0;
            //var sql = $"UPDATE play_live_goods SET MoneyType=@MoneyType WHERE id IN ({parameterNames})";
            //var parameters = new List<MySqlParameter>();
            //parameters.Add(new MySqlParameter("@MoneyType", MoneyType));
            //_dbContext.Database.ExecuteSqlRaw(sql, parameters);
            return Ok(1);
        }

        private void CallBack(object data)
        {
            int i = 0;
        }

        ///// <summary>
        ///// 消费
        ///// </summary>
        ///// <returns></returns>
        //[HttpGet]

        //public IActionResult kafkatest_xf()
        //{
        //    var consumer = SUPKafkaMessageCenter<string, string>.CreateTopicConsumer("192.168.12.101:9092");
        //    //绑定接收信息，回调函数
        //    consumer.onReceivedHandle += CallBack;

        //    var topics = new List<string>();
        //    topics.Add("kafka-default-topic");
        //    topics.Add("test");
        //    //订阅主题
        //    consumer.Subscribe(topics[0].ToLower(), false);
        //    return Ok(1);
        //}
        /// <summary>
        /// 生产
        /// </summary>
        /// <param name="topic">主题名称</param>
        /// <param name="jsondata">内容 对应他们的data</param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult kafkatest_Producer([FromForm] string topic, [FromForm] string jsondata)
        {
            //ISUPKafkaProducer<string, string> kafkaCenter = SUPKafkaMessageCenter<string, string>.CreateTopicProducer("61.132.89.53:3090");
            //kafkaCenter.Send("kafkatest2", jsondata, topic, deliveryReport =>
            //{
            //    int bb = 1000;

            //});

            var cc = KafakHelper.Producer(topic, jsondata);
            return Ok(1);
        }

        //public virtual IEnumerable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)

        //{

        //    IQueryable<T> query = _context.Set<T>();

        //    foreach (var includeProperty in includeProperties)

        //    {

        //        query = query.Include(includeProperty);

        //    }

        //    return query.AsEnumerable();

        //}

        /// <summary>
        /// 测试跨库查询
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult 测试跨库查询()
        {

            // _dbContext.SCL_Scl.

            var leftJoinSql = from student in _dbContext.SCL_Scl
                              join book in _dbContext.Ent_baseinfo_Ent on student.CompanyNo equals book.CompanyNo into temp
                              from tt in temp.DefaultIfEmpty()
                              select new
                              {
                                  sname = student.CompanyName,
                                  dsdsd=tt.CompanyName
                              };
            // var query = _dbContext.Ent_baseinfo_Ent.Include(b=>b.Scl_Scls).ThenInclude(x=>x.CompanyNo).ToList();
            return Ok(leftJoinSql.ToList());

        }
        /// <summary>
        /// 测试linq
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult testlinq()
        {
            //var query = _dbContext.DncPermission.AsQueryable();
            //var list = query.Paged(1, 100).Include(x => x.Menu).ToList();
            //var rightJoinSql2 = from book in _dbContext.DncPermission
            //                    join stu in _dbContext.DncMenu on book.MenuGuid equals stu.Guid into joinTemp
            //                    from tmp in joinTemp.DefaultIfEmpty()
            //                    select new
            //                    {
            //                        sname = tmp == null ? "" : tmp.Name,
            //                        bname = book.Name
            //                    };
            //// var query2=rightJoinSql2.Paged(1, 100);

            //var rightJoinSql3 = from book in _dbContext.DncPermission
            //                    join stu in _dbContext.DncMenu on book.MenuGuid equals stu.Guid

            //                    select new DncPermission
            //                    {
            //                        Name = book.Name
            //                    };

            // var query3 = rightJoinSql3.Paged(1, 100).ToList();

            //  var query4 =  _dbContext.DncPermission.Include(x => x.Menu).ToList();



            //var res =
            //    from a in _dbContext.DncPermission
            //    join b in _dbContext.DncMenu .Where(linq) on a.MenuGuid equals b.Guid

            //    select new DncPermission
            //    {
            //        Name = a.Name
            //    };

            Expression<Func<DncPermission, DncMenu, bool>> where = ((trr, ts) => trr.MenuGuid == ts.Guid);
            //var res = _dbContext<object>().Where(where);
            //Expression<Func<TaskRunRecord, TaskSet, bool>> exp1 = (trr, ts) => true;
            //Expression<Func<TaskRunRecord, TaskSet, bool>> exp2 = (trr, ts) => true;
            //Expression<Func<TaskRunRecord, TaskSet, bool>> exp3 = (trr, ts) => true;
            //Expression<Func<TaskRunRecord, TaskSet, bool>> exp4 = (trr, ts) => true;
            //if (!string.IsNullOrEmpty(taskName.Trim()))
            //{
            //    exp1 = (trr, ts) => ts.TaskName == taskName;
            //    where = ExpressionHelp.And(where, exp1);
            //}
            //if (!string.IsNullOrEmpty(userName.Trim()))
            //{
            //    exp2 = (trr, ts) => trr.UserName == userName;
            //    where = ExpressionHelp.And(where, exp2);
            //}
            //if (!string.IsNullOrEmpty(fromTime.Trim()))
            //{
            //    DateTime fromtt = GetDataTime(fromTime);
            //    exp3 = (trr, ts) => trr.StartTime >= fromtt;
            //    where = ExpressionHelp.And(where, exp3);
            //}
            //if (!string.IsNullOrEmpty(toTime.Trim()))
            //{
            //    exp4 = (trr, ts) => trr.StartTime <= GetDataTime(toTime);
            //    where = ExpressionHelp.And(where, exp4);
            //}
            return Ok(1);



        }
        private void hehe()
        {
            var conf = new ProducerConfig
            {
                BootstrapServers = "{集团kafka服务器}",
                BatchNumMessages = 1,
                CompressionType = Confluent.Kafka.CompressionType.Gzip,
                CompressionLevel = 9,
                MessageMaxBytes = 50 * 1024 * 1024 /* MB*KB*B*/,
            };
            var _kafkaProducer = new ProducerBuilder<Null, string>(conf).Build();

            var tarmsg = new Message<Null, string> { Value = "集团kafka服务器xiaoxi" };

            Task.Run(async () =>
            {
                await _kafkaProducer.ProduceAsync("001001U", tarmsg);
            }).Wait();
        }

        /// <summary>
        /// 生成EF Core 实体
        /// </summary>
        /// <param name="tablename">表明</param>
        /// <param name="db">数据库名</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult EfCoreMode([Required] string tablename, [Required] string db)
        {
            string content = "";
            using (_dbContext)
            {
                var tables = _dbContext.Database.GetDbConnection().GetSchema("Tables").Select($" TABLE_NAME='{tablename}'");
                tables = tables.ToList().Where(x => x.ItemArray[1].ToString() == db).ToArray();
                foreach (DataRow row in tables)
                {
                    string tableName = row["TABLE_NAME"].ToString();
                    string tableComment = row["TABLE_COMMENT"].ToString();

                    var schemaTable = _dbContext.Database.SqlQuery($"Select * From INFORMATION_SCHEMA.COLUMNS where table_name = '{tableName}'");
                    content = GenerateEntityContent(schemaTable, tableName, tableComment);
                    //string path = $"{Directory.GetCurrentDirectory().Substring(0, Directory.GetCurrentDirectory().IndexOf("bin"))}/Entitys/{tableName}.cs";
                    //System.IO.File.WriteAllBytes($"{Directory.GetCurrentDirectory().Substring(0, Directory.GetCurrentDirectory().IndexOf("bin"))}/Entitys/{tableName}.cs", Encoding.UTF8.GetBytes(content));
                }
            }
            return Ok(content);
        }
        [HttpGet]
        public IActionResult TestLinqDb(string tablename)
        {

            using (_dbContext)
            {
                int? cccccc = null;
                Expression<Func<law_law, bool>> criteria1 = p => true;

                criteria1 = criteria1.CheckNullAnd(x => x.LawName != tablename, tablename);

                criteria1 = criteria1.CheckNullAnd(x => x.Id > cccccc, cccccc);
                //  criteria1 = criteria1.CheckNullAnd(x => x.CompanyNo != "1", "1");
                var cc = _dbContext.Law_Law.Where(criteria1.Expand()).ToList();
                // _dbContext.Law_Law.Where(x => x.Id > 0).SetField(x => x.CreatedOn).WithValue(DateTime.Now).Update();
            }
            return Ok(1);
        }
        /// <summary>
        /// 测试微服务
        /// </summary>
        /// <param name="tablename"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> TesConsul(string tablename)
        {

            using (var consulClient = ConsulBuilderExtensions.GetConsulClient())
            {
                var services = consulClient.Catalog.Service("LAW").Result.Response;
                if (services != null && services.Any())
                {
                    // 模拟随机一台进行请求，这里只是测试，可以选择合适的负载均衡框架
                    var service = services.ElementAt(new Random().Next(services.Count()));
                    //三方
                    var RestSharpclient = new RestSharp.RestClient($"http://{service.ServiceAddress}:{service.ServicePort}");
                    //  var requestGet = new RestRequest("Authorzation/health", Method.GET);
                    //var requestGet = new RestRequest("Authorzation/{name}", Method.GET);
                    //requestGet.AddUrlSegment("name", "");
                    //IRestResponse response1 = RestSharpclient.Execute(requestGet);
                    // var contentGet = response1.Content;

                    //post 2

                    //var requestPost = new RestRequest("PersonInfoQuery/Info", Method.POST);
                    //Info info = new Info();
                    //info.ID = 1;
                    //info.Name = "张三";
                    //var json = JsonConvert.SerializeObject(info);
                    //requestPost.AddParameter("application/json", json, ParameterType.RequestBody);
                    //IRestResponse responsePost = client.Execute(requestPost);
                    //var contentPost = responsePost.Content;
                    //post
                    var requestPost = new RestRequest("api/lawsregulations/lawlawaddorupdate", Method.POST);
                    requestPost.AddJsonBody(new law_law() { LawName = "我的测试", Level = "国家级", Trade = "煤炭", LawType = "法律" });
                    var responsePost = await RestSharpclient.PostAsync<ResponseModel>(requestPost);



                    //自己手写
                    using (var client = _httpClientFactory.CreateClient())
                    {
                        var response = await client.GetAsync($"http://{service.ServiceAddress}:{service.ServicePort}/Authorzation/health");
                        var result = await response.Content.ReadAsStringAsync();
                        return Ok(result);
                    }
                }
            }
            var cc = _consulOption.ConsulIP;
            return Ok(1);
        }

        /// <summary>
        /// 修正数据类型
        /// </summary>
        /// <param name="content">数据库数据类型</param>
        /// <returns></returns>
        private string ChangeWords(string content)
        {
            string input = Regex.Replace(content, "nvarchar", "string");
            input = Regex.Replace(input, "bit", "bool");
            input = Regex.Replace(input, "varchar", "string");
            input = Regex.Replace(input, "text", "string");
            input = Regex.Replace(input, "ntext", "string");
            input = Regex.Replace(input, "nchar", "string");
            input = Regex.Replace(input, "char", "string");
            input = Regex.Replace(input, "tinyint", "bool");
            input = Regex.Replace(input, "smallint", "short");
            input = Regex.Replace(input, "bigint", "long");
            input = Regex.Replace(input, "numeric", "decimal");
            input = Regex.Replace(input, "money", "decimal");
            // input = Regex.Replace(input, "float", "double");
            input = Regex.Replace(input, "real", "float");
            input = Regex.Replace(input, "uniqueidentifier", "Guid");
            input = Regex.Replace(input, "datetime", "DateTime");
            input = Regex.Replace(input, "image", "byte[]");
            input = Regex.Replace(input, "binary", "byte[]");
            input = Regex.Replace(input, "date", "DateTime");

            return input;
        }
        private string GenerateEntityContent(DataTable dataTable, string tableName, string tableComment)
        {
            // var nameSpace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
            var nameSpace = " Cctegaq.Api";
            var stringBuilder = new StringBuilder();
            stringBuilder.AppendLine("using System;");
            stringBuilder.AppendLine("using System.Data;");
            stringBuilder.AppendLine("using System.ComponentModel.DataAnnotations;");
            stringBuilder.AppendLine("using System.ComponentModel.DataAnnotations.Schema;");

            stringBuilder.AppendLine($"namespace {nameSpace}.Entities");
            stringBuilder.AppendLine("{");
            string prefix = "\t";
            stringBuilder.AppendLine($"{prefix}/// <summary>");
            stringBuilder.AppendLine($"{prefix}///{tableComment}");
            stringBuilder.AppendLine($"{prefix}/// </summary>");
            stringBuilder.AppendLine($"{prefix}public class {tableName}");
            stringBuilder.AppendLine($"{prefix}{{");

            string filedPrefix = "\t\t";
            //默认在当前可执行目录下生成实体
            foreach (DataRow dataRow in dataTable.Rows)
            {
                //添加注释


                stringBuilder.AppendLine($"{filedPrefix}/// <summary>");
                stringBuilder.AppendLine($"{filedPrefix}///{dataRow["COLUMN_COMMENT"]}");
                stringBuilder.AppendLine($"{filedPrefix}/// </summary>");
                string dataType = ChangeWords(dataRow["DATA_TYPE"].ToString());
                string nullableStr = dataType != "string" && dataRow["IS_NULLABLE"].ToString() == "YES" ? "?" : "";
                // string defaultVlaue = dataRow["COLUMN_DEFAULT"].ToString() == string.Empty ? "" : $"={dataRow["COLUMN_DEFAULT"].ToString()};";
                //添加字段声明
                //  stringBuilder.AppendLine($"{filedPrefix}public {dataType}{nullableStr} {dataRow["COLUMN_NAME"]} {{ get; set; }} {defaultVlaue}");
                if (dataRow["COLUMN_NAME"].ToString().ToUpper() == "ID")
                {
                    stringBuilder.AppendLine($"{filedPrefix}[Key]{prefix}");
                    stringBuilder.AppendLine($"{filedPrefix}[DatabaseGenerated(DatabaseGeneratedOption.Identity)]{prefix}");

                }
                stringBuilder.AppendLine($"{filedPrefix}public {dataType}{nullableStr} {dataRow["COLUMN_NAME"]} {{ get; set; }} ");
                stringBuilder.AppendLine($"{prefix}");
            }

            stringBuilder.AppendLine($"{prefix}}}");
            stringBuilder.AppendLine($"}}");

            return stringBuilder.ToString();
        }


    }



}
